store QXmlStreamAttributes in xml_tag. (#441)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Sat, 28 Dec 2019 19:01:03 +0000 (12:01 -0700)
committerGitHub <noreply@github.com>
Sat, 28 Dec 2019 19:01:03 +0000 (12:01 -0700)
* store QXmlStreamAttributes in xml_tag.

instead of arrays of char strings.  This simplified xml_tag
handling.

Correct encoding issues with text and html formats.

Enhance test coverage of text and html formats.

* clean up xml attributes handling.

defs.h
gpx.cc
html.cc
kml.cc
reference/gc/GC7FA4.html [new file with mode: 0644]
reference/gc/GC7FA4.text [new file with mode: 0644]
src/core/xmltag.h
testo.d/text.test
text.cc
util.cc
xmltag.cc

diff --git a/defs.h b/defs.h
index fcec22b3fafe428071d9892b24be4ed2f3e78d11..1f0a995a043541da65c61344c9a64af85bb1fb74 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -298,12 +298,12 @@ using fs_copy = void (*)(void**, void*);
 using fs_convert = void (*)(void*);
 
 struct format_specific_data {
-  long type;
-  format_specific_data* next;
+  long type{0};
+  format_specific_data* next{nullptr};
 
-  fs_destroy destroy;
-  fs_copy copy;
-  fs_convert convert;
+  fs_destroy destroy{nullptr};
+  fs_copy copy{nullptr};
+  fs_convert convert{nullptr};
 };
 
 class gb_color
diff --git a/gpx.cc b/gpx.cc
index 78e6fa10b3ba4b5e2be8d67769caf0bebeae5a09..793922b510e53b59febbb6d46975f75a304ad29b 100644 (file)
--- a/gpx.cc
+++ b/gpx.cc
@@ -560,25 +560,23 @@ start_something_else(const QString& el, const QXmlStreamAttributes& attr)
   auto* new_tag = new xml_tag;
   new_tag->tagname = el;
 
-  int attr_count = attr.size();
-  const QXmlStreamNamespaceDeclarations nsdecl = reader->namespaceDeclarations();
-  const int ns_count = nsdecl.size();
-  new_tag->attributes = (char**)xcalloc(sizeof(char*),2*(attr_count+ns_count)+1);
-  char** avcp = new_tag->attributes;
-  for (int i = 0; i < attr_count; i++)  {
-    *avcp = xstrdup(attr[i].qualifiedName().toString());
-    avcp++;
-    *avcp = xstrdup(attr[i].value().toString());
-    avcp++;
-  }
-  for (int i = 0; i < ns_count; i++)  {
-    *avcp = xstrdup(nsdecl[i].prefix().toString().prepend(nsdecl[i].prefix().isEmpty()? "xmlns" : "xmlns:"));
-    avcp++;
-    *avcp = xstrdup(nsdecl[i].namespaceUri().toString());
-    avcp++;
-  }
-
-  *avcp = nullptr; // this indicates the end of the attribute name value pairs.
+  const QXmlStreamNamespaceDeclarations ns = reader->namespaceDeclarations();
+  new_tag->attributes.reserve(attr.size() + ns.size());
+  /*
+   * It was found to be faster to append one element at a time compared to
+   *   a) assiging new_tag->attributes = attr, or
+   *   b) appending in one step, new_tag.attributes.apppend(attr)
+   * Tested with on ubuntu bioinic with Qt 5.9.5 and a large Geocache file
+   * generated by Groundspeak.
+   */
+  for (const auto& a : attr) {
+    new_tag->attributes.append(a);
+  }
+  for (const auto& n : ns) {
+    QString prefix = n.prefix().toString().prepend(n.prefix().isEmpty()? "xmlns" : "xmlns:");
+    QString namespaceUri = n.namespaceUri().toString();
+    new_tag->attributes.append(prefix, namespaceUri);
+  }
 
   if (cur_tag) {
     if (cur_tag->child) {
@@ -1485,14 +1483,10 @@ gpx_read()
 }
 
 static void
-write_tag_attributes(xml_tag* tag)
+write_attributes(const QXmlStreamAttributes& attributes)
 {
-  char** pa = tag->attributes;
-  if (pa) {
-    while (*pa) {
-      writer->writeAttribute(pa[0], pa[1]);
-      pa += 2;
-    }
+  for (const auto& attribute : attributes) {
+    writer->writeAttribute(attribute.qualifiedName().toString(), attribute.value().toString());
   }
 }
 
@@ -1501,14 +1495,11 @@ fprint_xml_chain(xml_tag* tag, const Waypoint* wpt)
 {
   while (tag) {
     writer->writeStartElement(tag->tagname);
-
+    write_attributes(tag->attributes);
     if (tag->cdata.isEmpty() && !tag->child) {
-      write_tag_attributes(tag);
       // No children?  Self-closing tag.
       writer->writeEndElement();
     } else {
-      write_tag_attributes(tag);
-
       if (!tag->cdata.isEmpty()) {
         writer->writeCharacters(tag->cdata);
       }
@@ -1531,28 +1522,6 @@ fprint_xml_chain(xml_tag* tag, const Waypoint* wpt)
   }
 }
 
-void free_gpx_extras(xml_tag* tag)
-{
-  while (tag) {
-    if (tag->child) {
-      free_gpx_extras(tag->child);
-    }
-    if (tag->attributes) {
-      char** ap = tag->attributes;
-
-      while (*ap) {
-        xfree(*ap++);
-      }
-
-      xfree(tag->attributes);
-    }
-
-    xml_tag* next = tag->sibling;
-    delete tag;
-    tag = next;
-  }
-}
-
 /*
  * Handle the grossness of GPX 1.0 vs. 1.1 handling of linky links.
  */
diff --git a/html.cc b/html.cc
index 0f7e19b7c5a060687595aca1f3abb345f327b95e..5f2d56f64566cf8de7d2fcc6f0c630457f1862f4 100644 (file)
--- a/html.cc
+++ b/html.cc
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
 
+#include <cstdint>
+#include <ctime>                   // for localtime
+
+#include <QtCore/QString>          // for QString, operator!=
+#include <QtCore/QVector>          // for QVector
+#include <QtCore/Qt>               // for CaseInsensitive
 
 #include "defs.h"
-#include "jeeps/gpsmath.h"
-#include "src/core/xmltag.h"
-#include <cstdio>
-#include <cstdlib>
+#include "gbfile.h"                // for gbfprintf, gbfclose, gbfopen, gbfputs, gbfile
+#include "jeeps/gpsmath.h"         // for GPS_Math_WGS84_To_UTM_EN
+#include "src/core/datetime.h"     // for DateTime
+#include "src/core/xmltag.h"       // for xml_findfirst, xml_attribute, xml_tag, fs_xml, xml_findnext
+
 
 static gbfile* file_out;
 static short_handle mkshort_handle;
@@ -89,9 +96,9 @@ html_disp(const Waypoint* wpt)
   GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
                            &utme, &utmn, &utmz, &utmzc);
 
-  gbfprintf(file_out, "\n<a name=\"%s\"><hr></a>\n", CSTRc(wpt->shortname));
+  gbfprintf(file_out, "\n<a name=\"%s\"><hr></a>\n", CSTR(wpt->shortname));
   gbfprintf(file_out, "<table width=\"100%%\">\n");
-  gbfprintf(file_out, "<tr><td><p class=\"gpsbabelwaypoint\">%s - ",(global_opts.synthesize_shortnames) ? CSTRc(mkshort_from_wpt(mkshort_handle, wpt)) : CSTRc(wpt->shortname));
+  gbfprintf(file_out, "<tr><td><p class=\"gpsbabelwaypoint\">%s - ",(global_opts.synthesize_shortnames) ? CSTR(mkshort_from_wpt(mkshort_handle, wpt)) : CSTR(wpt->shortname));
   char* cout = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", 1);
   gbfprintf(file_out, "%s (%d%c %6.0f %7.0f)", cout, utmz, utmzc, utme, utmn);
   xfree(cout);
@@ -101,12 +108,12 @@ html_disp(const Waypoint* wpt)
   gbfprintf(file_out, "<br>\n");
   if (wpt->description != wpt->shortname) {
     if (wpt->HasUrlLink()) {
-      char* d = html_entitize(CSTRc(wpt->description));
+      char* d = html_entitize(CSTR(wpt->description));
       UrlLink link = wpt->GetUrlLink();
       gbfprintf(file_out, "<a href=\"%s\">%s</a>", CSTR(link.url_), d);
       xfree(d);
     } else {
-      gbfprintf(file_out, "%s", CSTRc(wpt->description));
+      gbfprintf(file_out, "%s", CSTR(wpt->description));
     }
     if (!wpt->gc_data->placer.isEmpty()) {
       gbfprintf(file_out, " by %s", CSTR(wpt->gc_data->placer));
@@ -146,7 +153,7 @@ html_disp(const Waypoint* wpt)
     }
     gbfprintf(file_out, "<p class=\"gpsbabelhint\"><strong>Hint:</strong> %s</p>\n", CSTR(hint));
   } else if (!wpt->notes.isEmpty() && (wpt->description.isEmpty() || wpt->notes != wpt->description)) {
-    gbfprintf(file_out, "<p class=\"gpsbabelnotes\">%s</p>\n", CSTRc(wpt->notes));
+    gbfprintf(file_out, "<p class=\"gpsbabelnotes\">%s</p>\n", CSTR(wpt->notes));
   }
 
   fs_xml* fs_gpx = nullptr;
@@ -188,17 +195,9 @@ html_disp(const Waypoint* wpt)
 
       logpart = xml_findfirst(curlog, "groundspeak:log_wpt");
       if (logpart) {
-        double lat = 0;
-        double lon = 0;
-        char* coordstr = xml_attribute(logpart, "lat");
-        if (coordstr) {
-          lat = atof(coordstr);
-        }
-        coordstr = xml_attribute(logpart, "lon");
-        if (coordstr) {
-          lon = atof(coordstr);
-        }
-        coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 1);
+        double lat = xml_attribute(logpart->attributes, "lat").toDouble();
+        double lon = xml_attribute(logpart->attributes, "lon").toDouble();
+        char* coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 1);
         gbfprintf(file_out,
                   "<span class=\"gpsbabellogcoords\">%s</span><br>\n",
                   coordstr);
@@ -207,8 +206,8 @@ html_disp(const Waypoint* wpt)
 
       logpart = xml_findfirst(curlog, "groundspeak:text");
       if (logpart) {
-        char* encstr = xml_attribute(logpart, "encoded");
-        int encoded = (toupper(encstr[0]) != 'F');
+        QString encstr = xml_attribute(logpart->attributes, "encoded");
+        bool encoded = !encstr.startsWith('F', Qt::CaseInsensitive);
 
         QString s;
         if (html_encrypt && encoded) {
diff --git a/kml.cc b/kml.cc
index 08f147e67689aa1da014cfb52ee8ae15605ce47b..da43ac2765d33956ec8f859e1f8b48ce8984902d 100644 (file)
--- a/kml.cc
+++ b/kml.cc
 # include <windows.h>
 #endif
 
-#include <cctype>                      // for tolower, toupper
-#include <cmath>                       // for fabs
-#include <cstdio>                      // for sscanf, printf
-#include <cstdlib>                     // for atoi, atol, atof
-#include <cstring>                     // for strcmp
-#include <tuple>                       // for tuple, make_tuple, tie
-
-#include <QtCore/QByteArray>           // for QByteArray
-#include <QtCore/QChar>                // for QChar
-#include <QtCore/QDate>                // for QDate
-#include <QtCore/QDateTime>            // for QDateTime
-#include <QtCore/QFile>                // for QFile
-#include <QtCore/QIODevice>            // for operator|, QIODevice, QIODevice::Text, QIODevice::WriteOnly
-#include <QtCore/QList>                // for QList
-#include <QtCore/QStaticStringData>    // for QStaticStringData
-#include <QtCore/QString>              // for QString, QStringLiteral, operator+, operator!=
-#include <QtCore/QXmlStreamAttributes> // for QXmlStreamAttributes
-#include <QtCore/Qt>                   // for ISODate
-#include <QtCore/QtGlobal>             // for foreach, qint64, qPrintable
+#include <cctype>                       // for tolower, toupper
+#include <cmath>                        // for fabs
+#include <cstdio>                       // for sscanf, printf
+#include <cstdlib>                      // for atoi, atol, atof
+#include <cstring>                      // for strcmp
+#include <tuple>                        // for tuple, make_tuple, tie
+
+#include <QtCore/QByteArray>            // for QByteArray
+#include <QtCore/QChar>                 // for QChar
+#include <QtCore/QDate>                 // for QDate
+#include <QtCore/QDateTime>             // for QDateTime
+#include <QtCore/QFile>                 // for QFile
+#include <QtCore/QIODevice>             // for operator|, QIODevice, QIODevice::Text, QIODevice::WriteOnly
+#include <QtCore/QList>                 // for QList
+#include <QtCore/QStaticStringData>     // for QStaticStringData
+#include <QtCore/QString>               // for QString, QStringLiteral, operator+, operator!=
+#include <QtCore/QStringList>           // for QStringList
+#include <QtCore/QVector>               // for QVector
+#include <QtCore/QXmlStreamAttributes>  // for QXmlStreamAttributes
+#include <QtCore/Qt>                    // for ISODate
+#include <QtCore/QtGlobal>              // for foreach, qint64, qPrintable
 
 #include "defs.h"
 #include "grtcirc.h"                    // for RAD, gcdist, radtometers
 #include "src/core/datetime.h"          // for DateTime
 #include "src/core/file.h"              // for File
+#include "src/core/logging.h"           // for Warning, Fatal
 #include "src/core/optional.h"          // for optional
-#include <src/core/logging.h>           // for Warning
 #include "src/core/xmlstreamwriter.h"   // for XmlStreamWriter
 #include "src/core/xmltag.h"            // for xml_findfirst, xml_tag, fs_xml, xml_attribute, xml_findnext
+#include "units.h"                      // for fmt_setunits, fmt_speed, fmt_altitude, fmt_distance, units_aviation, units_metric, units_nautical, units_statute
 #include "xmlgeneric.h"                 // for cb_cdata, cb_end, cb_start, xg_callback, xg_string, xg_cb_type, xml_deinit, xml_ignore_tags, xml_init, xml_read, xg_tag_mapping
-#include "units.h"
+
 
 // options
 static char* opt_deficon = nullptr;
@@ -1461,8 +1464,8 @@ static QString kml_geocache_get_logs(const Waypoint* wpt)
 
     logpart = xml_findfirst(curlog, "groundspeak:text");
     if (logpart) {
-      char* encstr = xml_attribute(logpart, "encoded");
-      int encoded = (toupper(encstr[0]) != 'F');
+      QString encstr = xml_attribute(logpart->attributes, "encoded");
+      bool encoded = !encstr.startsWith('F', Qt::CaseInsensitive);
 
       QString s;
       if (html_encrypt && encoded) {
diff --git a/reference/gc/GC7FA4.html b/reference/gc/GC7FA4.html
new file mode 100644 (file)
index 0000000..7c3987d
--- /dev/null
@@ -0,0 +1,114 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+ <title>GPSBabel HTML Output</title>
+ <style>
+  p.gpsbabelwaypoint { font-size: 120%; font-weight: bold }
+ </style>
+</head>
+<body>
+<p class="index">
+<a href="#GC7FA4">GC7FA4 - Points géodésiques du Québec</a><br>
+</p>
+
+<a name="GC7FA4"><hr></a>
+<table width="100%">
+<tr><td><p class="gpsbabelwaypoint">GC7FA4 - N46&deg;08.000 W73&deg;00.000 (18T 654491 5110806)<br>
+<a href="http://www.geocaching.com/seek/cache_details.aspx?guid=727f9d2c-f080-41f1-a2c9-a326ead462ed">Points géodésiques du Québec</a> by Sverdrup2</p></td>
+<td align="right"><p class="gpsbabelcacheinfo">1 / 1<br>
+Locationless (Reverse) Cache / Virtual</p></td></tr>
+<tr><td colspan="2"><p class="gpsbabeldescshort">LES COORDONÉES PUBLIÉES NE REPRÉSENTENT PAS LA LOCALISATION D'UNE CACHE
+PUBLISHED COORDINATES DO NOT REPRESENT THE LOCALIZATION OF A CACHE</p>
+<p class="gpsbabeldesclong">Le but de cette cache virtuelle est de trouver les points géodésiques du territoire québécois. Les points géodésiques sont faciles à identifier (capuchons de laiton au niveau du sol). Généralement, il y a un panneau de couleur orange sur un poteau à proximité du point. Sur ce panneau, le numéro du point est identifié. Aussi, la distance relative du panneau au point est indiquée. 
+<P>
+Pour inscrire votre découverte, vous devez prendre en note le NUMÉRO DU POINT(inscrit sur le point même ou au centre du panneau)LA COORDONNÉE(en format HDDD MM.MM WGS84 datum ET UTM NAD83 indiquer la zone SVP)et L'ALTITUDE RELATIVE. Si le points n'est pas visible (il se peut qu'il soit sous quelques centimètres de terre) vous pouvez prendre la coordonnée à l'emplacement du panneau SI LA PRÉCISION DE VOTRE GPS EST SUPÉRIEUR À LA DISTANCE INSCRITE SUR LE PANNEAU (ex : Précison du GPS de 5m et distance au point inscrite sur le panneau de 3m).
+<P>
+Une photo du point ou du panneau et une description générale des lieux serait aussi des informations importantes.
+<P>
+Enfin, il faudrait aussi prendre en note l'organisme propriétaire du point géodésique. Au Québec il en existe plusieurs:
+<P>
+Le Service de la géodésie du Québec, Ministère des Ressources naturelles, Québec
+<P>
+La Division des levés géodésiques, Géomatique Canada, Secteur des sciences de la terre Ressources naturelles Canada 
+<P>
+Le Service hydrographique du Canada, Direction des sciences, Pêches et Océans Canada et la Garde côtière canadienne, Pêches et Océans Canada 
+<P>
+Et tout les anciens noms de ministères et/ou organisme
+<P>
+Des photos de points de même que des panneaux suivront bientôt.
+VOUS NE POUVEZ INSCRIRE QU'UN SEUL POINT GÉODÉSIQUE (UN POINT PAR GÉOCACHEUR)
+Bonne chance!
+
+<P>
+
+The goal of this virtual cache is to find the geodetic points of Québec’s territory. The geodetic points are easy to identify (Brass cap at ground level) Generally, there is an orange panel of on a post near the point. On this panel, the number of the point is identified. Also, the distance relating from the panel to the point is also indicated. In order to log your find, you must take in note THE NUMBER OF THE POINT(registered on the point or in the center of the panel) and THE COORDINATES(in format HDDD MM.MM WGS84 datum AND UTM NAD83 indicate the zone please)and THE ALTITUDE. If the point is not visible (it may be buried under few centimetres) you can take the coordinate at the panel IF THE ACCURACY OF YOUR GPS IS HIGHER Than the DISTANCE REGISTERED ON the PANEL. (Ex: accuracy of the GPS is 5m and the distance to the point registered on the panel is 3m). 
+ <P>
+A picture of the point or panel and a general description of the places would be also significant information. Finally, it would also be important to take in note the organization owner of the geodetic point. 
+In Quebec there are several: 
+<P>
+The "Service de la géodésie du Québec, Ministère des Ressources naturelles Québec"
+The Geodetic Survey Division, Geomatics Canada, Earth Sciences Sector, Natural Resources Canada 
+The Canadian Hydrographic Service, Sciences Directorate, Fisheries and Oceans Canada and the Canadian Coast Guard, Fisheries and Oceans Canada
+And all old names of ministries and/or organization
+<P>
+
+PICTURES of points and of the panels will follow soon. YOU CAN ONLY LOG ONE POINT (ONE POINT PER GEOCACHER)
+Good luck!</p>
+<p class="gpsbabellog">
+<span class="gpsbabellogtype">Found it</span> by <span class="gpsbabellogfinder">Christopher R &amp; Pooh B</span> on <span class="gpsbabellogdate">2005-07-12</span><br>
+<span class="gpsbabellogcoords">N48&deg;10.207 W53&deg;58.097</span><br>
+This marker is not in Quebec but it is a Geodesic marker in Clarenville, Newfoundland, Canada!
+
+Found this one while hunting a traditional cache and thought of this cache right away! 
+
+It is located on Bare Mountain in Clarenville - There are aactually two markers within 15 feet of one another on Bare Mountain...
+
+Smiles Pooh Bear 
+
+Ce marqueur n'est pas au Québec mais c'est un marqueur géodésique dans Clarenville, Terre-Neuve, Canada!  
+
+A trouvé celui-ci tandis que chasse une cachette traditionnelle et pensé à cette cachette tout de suite!  Elle est située sur la montagne nue dans Clarenville - il y a aactually deux marqueurs à moins de 15 pieds d'un des autres sur la montagne nue...  Ours De Pooh De Sourires</p>
+<p class="gpsbabellog">
+<span class="gpsbabellogtype">Found it</span> by <span class="gpsbabellogfinder">TravelBen</span> on <span class="gpsbabellogdate">2005-06-26</span><br>
+<span class="gpsbabellogcoords">N45&deg;26.872 W73&deg;56.410</span><br>
+[:D] 14h22
+
+Marqueur du Service de la Géodégie (c'est bien un &quot;g&quot; pas un &quot;s&quot;) du Québec.
+
+Position Average (100 échantillons):
+N 45° 26.872 W 075° 56.410, 21 mètres d'altitude
+UTM: 18T E 582877 N 5033250
+
+Ce marqueur se trouve dans le ville de Senneville, sur un monument décrivant une page d'histoire du Québec, sur le bas côté avant droit.
+
+Près de la cache:  Exo-07 La Jumelle de Loudiver (GCP3VE)</p>
+<p class="gpsbabellog">
+<span class="gpsbabellogtype">Found it</span> by <span class="gpsbabellogfinder">etasse</span> on <span class="gpsbabellogdate">2005-06-03</span><br>
+<span class="gpsbabellogcoords">N45&deg;29.525 W75&deg;43.005</span><br>
+MRN marker 94K4731 in Gatineau, QC. corner of Du Rhone and Gatineau Ave.
+
+Position Average
+N 45° 29.5247  W 075° 43.0049  59.49m
+UTM 18T 0443995 5037866
+
+Least Squares Average
+N 45° 29.5257  W 075° 43.0043  55.74m
+UTM 18T 0443996 5037868
+
+This pole has everything:  An underground cable warning, a geodesic mark, a bus stop and a garage sale sign.
+
+Judging by the coordinates it looks like the coords should be 45°29'31.5&quot; -75°43'0&quot;  I placed the GPS antenna right against the marker, to no avail.</p>
+<p class="gpsbabellog">
+<span class="gpsbabellogtype">Found it</span> by <span class="gpsbabellogfinder">Katou</span> on <span class="gpsbabellogdate">2005-06-03</span><br>
+<span class="gpsbabellogcoords">N46&deg;37.091 W71&deg;55.974</span><br>
+Un bo point géodésique a Lotbinière..en allant faire une nouvelle cache a l'île richelieu ;-)</p>
+<p class="gpsbabellog">
+<span class="gpsbabellogtype">Found it</span> by <span class="gpsbabellogfinder">Gps_Gulliver&amp;DauphinBleu</span> on <span class="gpsbabellogdate">2005-05-29</span><br>
+<span class="gpsbabellogcoords">N45&deg;32.449 W73&deg;30.747</span><br>
+Point Geodesique situe near Port de Plaisance de Longueuil
+sur le bord du fleuve st-laurent.
+Il y a des sentiers et une grande piste cyclable
+Enjoy !</p>
+</td></tr></table>
+</body></html>
\ No newline at end of file
diff --git a/reference/gc/GC7FA4.text b/reference/gc/GC7FA4.text
new file mode 100644 (file)
index 0000000..51dfba9
--- /dev/null
@@ -0,0 +1,76 @@
+-----------------------------------------------------------------------------
+GC7FA4                             N46 08.000 W73 00.000 (18T 654491 5110806)
+Points géodésiques du Québec by Sverdrup2 - Locationless (Reverse) Cache / Virtual - (1 / 1)
+
+LES COORDONÉES PUBLIÉES NE REPRÉSENTENT PAS LA LOCALISATION D'UNE CACHE PUBLISHED COORDINATES DO NOT REPRESENT THE LOCALIZATION OF A CACHE
+
+Le but de cette cache virtuelle est de trouver les points géodésiques du territoire québécois. Les points géodésiques sont faciles à identifier (capuchons de laiton au niveau du sol). Généralement, il y a un panneau de couleur orange sur un poteau à proximité du point. Sur ce panneau, le numéro du point est identifié. Aussi, la distance relative du panneau au point est indiquée.  
+ Pour inscrire votre découverte, vous devez prendre en note le NUMÉRO DU POINT(inscrit sur le point même ou au centre du panneau)LA COORDONNÉE(en format HDDD MM.MM WGS84 datum ET UTM NAD83 indiquer la zone SVP)et L'ALTITUDE RELATIVE. Si le points n'est pas visible (il se peut qu'il soit sous quelques centimètres de terre) vous pouvez prendre la coordonnée à l'emplacement du panneau SI LA PRÉCISION DE VOTRE GPS EST SUPÉRIEUR À LA DISTANCE INSCRITE SUR LE PANNEAU (ex : Précison du GPS de 5m et distance au point inscrite sur le panneau de 3m). 
+ Une photo du point ou du panneau et une description générale des lieux serait aussi des informations importantes. 
+ Enfin, il faudrait aussi prendre en note l'organisme propriétaire du point géodésique. Au Québec il en existe plusieurs: 
+ Le Service de la géodésie du Québec, Ministère des Ressources naturelles, Québec 
+ La Division des levés géodésiques, Géomatique Canada, Secteur des sciences de la terre Ressources naturelles Canada  
+ Le Service hydrographique du Canada, Direction des sciences, Pêches et Océans Canada et la Garde côtière canadienne, Pêches et Océans Canada  
+ Et tout les anciens noms de ministères et/ou organisme 
+ Des photos de points de même que des panneaux suivront bientôt. VOUS NE POUVEZ INSCRIRE QU'UN SEUL POINT GÉODÉSIQUE (UN POINT PAR GÉOCACHEUR) Bonne chance! 
+ The goal of this virtual cache is to find the geodetic points of Québec’s territory. The geodetic points are easy to identify (Brass cap at ground level) Generally, there is an orange panel of on a post near the point. On this panel, the number of the point is identified. Also, the distance relating from the panel to the point is also indicated. In order to log your find, you must take in note THE NUMBER OF THE POINT(registered on the point or in the center of the panel) and THE COORDINATES(in format HDDD MM.MM WGS84 datum AND UTM NAD83 indicate the zone please)and THE ALTITUDE. If the point is not visible (it may be buried under few centimetres) you can take the coordinate at the panel IF THE ACCURACY OF YOUR GPS IS HIGHER Than the DISTANCE REGISTERED ON the PANEL. (Ex: accuracy of the GPS is 5m and the distance to the point registered on the panel is 3m).  
+ A picture of the point or panel and a general description of the places would be also significant information. Finally, it would also be important to take in note the organization owner of the geodetic point.  In Quebec there are several:  
+ The "Service de la géodésie du Québec, Ministère des Ressources naturelles Québec" The Geodetic Survey Division, Geomatics Canada, Earth Sciences Sector, Natural Resources Canada  The Canadian Hydrographic Service, Sciences Directorate, Fisheries and Oceans Canada and the Canadian Coast Guard, Fisheries and Oceans Canada And all old names of ministries and/or organization 
+ PICTURES of points and of the panels will follow soon. YOU CAN ONLY LOG ONE POINT (ONE POINT PER GEOCACHER) Good luck!
+
+Found it by Christopher R & Pooh B on 2005-07-12
+N48 10.207 W53 58.097
+This marker is not in Quebec but it is a Geodesic marker in Clarenville, Newfoundland, Canada!
+
+Found this one while hunting a traditional cache and thought of this cache right away! 
+
+It is located on Bare Mountain in Clarenville - There are aactually two markers within 15 feet of one another on Bare Mountain...
+
+Smiles Pooh Bear 
+
+Ce marqueur n'est pas au Québec mais c'est un marqueur géodésique dans Clarenville, Terre-Neuve, Canada!  
+
+A trouvé celui-ci tandis que chasse une cachette traditionnelle et pensé à cette cachette tout de suite!  Elle est située sur la montagne nue dans Clarenville - il y a aactually deux marqueurs à moins de 15 pieds d'un des autres sur la montagne nue...  Ours De Pooh De Sourires
+
+Found it by TravelBen on 2005-06-26
+N45 26.872 W73 56.410
+[:D] 14h22
+
+Marqueur du Service de la Géodégie (c'est bien un "g" pas un "s") du Québec.
+
+Position Average (100 échantillons):
+N 45° 26.872 W 075° 56.410, 21 mètres d'altitude
+UTM: 18T E 582877 N 5033250
+
+Ce marqueur se trouve dans le ville de Senneville, sur un monument décrivant une page d'histoire du Québec, sur le bas côté avant droit.
+
+Près de la cache:  Exo-07 La Jumelle de Loudiver (GCP3VE)
+
+Found it by etasse on 2005-06-03
+N45 29.525 W75 43.005
+MRN marker 94K4731 in Gatineau, QC. corner of Du Rhone and Gatineau Ave.
+
+Position Average
+N 45° 29.5247  W 075° 43.0049  59.49m
+UTM 18T 0443995 5037866
+
+Least Squares Average
+N 45° 29.5257  W 075° 43.0043  55.74m
+UTM 18T 0443996 5037868
+
+This pole has everything:  An underground cable warning, a geodesic mark, a bus stop and a garage sale sign.
+
+Judging by the coordinates it looks like the coords should be 45°29'31.5" -75°43'0"  I placed the GPS antenna right against the marker, to no avail.
+
+Found it by Katou on 2005-06-03
+N46 37.091 W71 55.974
+Un bo point géodésique a Lotbinière..en allant faire une nouvelle cache a l'île richelieu ;-)
+
+Found it by Gps_Gulliver&DauphinBleu on 2005-05-29
+N45 32.449 W73 30.747
+Point Geodesique situe near Port de Plaisance de Longueuil
+sur le bord du fleuve st-laurent.
+Il y a des sentiers et une grande piste cyclable
+Enjoy !
+
+-----------------------------------------------------------------------------
index 89a470ead40521d2b13653b6e3289d808ead9603..4bdae190ad9ef430073b01f1974df4703d9d1ced 100644 (file)
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
  */
-class xml_tag {
- public:
-  xml_tag() :
-    attributes(nullptr),
-    parent(nullptr),
-    sibling(nullptr),
-    child(nullptr) {}
+#ifndef SRC_CORE_XMLTAG_H
+#define SRC_CORE_XMLTAG_H
 
+#include <QtCore/QString>                          // for QString
+#include <QtCore/QXmlStreamAttributes>             // for QXmlStreamAttributes
+
+#include "defs.h"
+
+class xml_tag
+{
+public:
   QString tagname;
   QString cdata;
   QString parentcdata;
-  char** attributes;
-  xml_tag* parent;
-  xml_tag* sibling;
-  xml_tag* child;
+  QXmlStreamAttributes attributes;
+  xml_tag* parent{nullptr};
+  xml_tag* sibling{nullptr};
+  xml_tag* child{nullptr};
 };
 
-xml_tag* xml_findfirst(xml_tag* root, const char* tagname);
-xml_tag* xml_findnext(xml_tag* root, xml_tag* cur, const char* tagname);
-char* xml_attribute(xml_tag* tag, const char* attrname);
-void free_gpx_extras(xml_tag* tag);
+xml_tag* xml_findfirst(xml_tag* root, const QString& tagname);
+xml_tag* xml_findnext(xml_tag* root, xml_tag* cur, const QString& tagname);
+QString xml_attribute(const QXmlStreamAttributes& attributes, const QString& attrname);
 
 struct fs_xml {
   format_specific_data fs;
-  xml_tag* tag;
+  xml_tag* tag{nullptr};
 };
 
 fs_xml* fs_xml_alloc(long type);
+
+#endif // SRC_CORE_XMLTAG_H
index df5bbbc553704052e9d3901cc79517cbda6e6945..b60fb4ea4cd81bbeb688d367eb6d89d0754e5dbd 100644 (file)
@@ -10,3 +10,9 @@ compare ${REFERENCE}/gc/GCGCA8~html.txt ${TMPDIR}/gc.html
 
 gpsbabel -i gpx -f ${REFERENCE}/gc/GCGCA8.gpx -o html,logs -F ${TMPDIR}/gc_logs.html
 compare ${REFERENCE}/gc/GCGCA8_logs~html.txt ${TMPDIR}/gc_logs.html
+
+gpsbabel -i gpx -f ${REFERENCE}/gc/GC7FA4.gpx \
+  -o html,logs -F ${TMPDIR}/GC7FA4.html \
+  -o text,logs -F ${TMPDIR}/GC7FA4.text
+compare ${REFERENCE}/gc/GC7FA4.html ${TMPDIR}/GC7FA4.html
+compare ${REFERENCE}/gc/GC7FA4.text ${TMPDIR}/GC7FA4.text
diff --git a/text.cc b/text.cc
index ed8fc063a868926b8316dcf2d3c60d080f2cb34d..3b6b1302791bb79dba6dedf66c5049defc084e57 100644 (file)
--- a/text.cc
+++ b/text.cc
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
 
+#include <cstdint>
+#include <ctime>                   // for localtime
+
+#include <QtCore/QString>          // for QString, operator!=
+#include <QtCore/QVector>          // for QVector
+#include <QtCore/Qt>               // for CaseInsensitive
 
 #include "defs.h"
-#include "jeeps/gpsmath.h"
-#include "src/core/xmltag.h"
-#include <cctype>
-#include <cstdlib>
+#include "gbfile.h"                // for gbfprintf, gbfputs, gbfclose, gbfopen, gbfile
+#include "jeeps/gpsmath.h"         // for GPS_Math_WGS84_To_UTM_EN
+#include "src/core/datetime.h"     // for DateTime
+#include "src/core/xmltag.h"       // for xml_findfirst, xml_attribute, xml_tag, fs_xml, xml_findnext
+
 
 static gbfile* file_out;
 static short_handle mkshort_handle;
@@ -120,7 +127,7 @@ text_disp(const Waypoint* wpt)
   }
   xasprintf(&tmpout2, "%s (%d%c %6.0f %7.0f)%s", tmpout1, utmz, utmzc, utme, utmn, altout);
   gbfprintf(file_out, "%-16s  %59s\n",
-            (global_opts.synthesize_shortnames) ? CSTRc(mkshort_from_wpt(mkshort_handle, wpt)) : CSTRc(wpt->shortname),
+            (global_opts.synthesize_shortnames) ? CSTR(mkshort_from_wpt(mkshort_handle, wpt)) : CSTR(wpt->shortname),
             tmpout2);
   xfree(tmpout2);
   xfree(tmpout1);
@@ -204,25 +211,17 @@ text_disp(const Waypoint* wpt)
 
       logpart = xml_findfirst(curlog, "groundspeak:log_wpt");
       if (logpart) {
-        double lat = 0;
-        double lon = 0;
-        char* coordstr = xml_attribute(logpart, "lat");
-        if (coordstr) {
-          lat = atof(coordstr);
-        }
-        coordstr = xml_attribute(logpart, "lon");
-        if (coordstr) {
-          lon = atof(coordstr);
-        }
-        coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 0);
+        double lat = xml_attribute(logpart->attributes, "lat").toDouble();
+        double lon = xml_attribute(logpart->attributes, "lon").toDouble();
+        char* coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 0);
         gbfprintf(file_out, "%s\n", coordstr);
         xfree(coordstr);
       }
 
       logpart = xml_findfirst(curlog, "groundspeak:text");
       if (logpart) {
-        char* encstr = xml_attribute(logpart, "encoded");
-        int encoded = (toupper(encstr[0]) != 'F');
+        QString encstr = xml_attribute(logpart->attributes, "encoded");
+        bool encoded = !encstr.startsWith('F', Qt::CaseInsensitive);
 
         QString s;
         if (txt_encrypt && encoded) {
diff --git a/util.cc b/util.cc
index 6eeaff238e8e43b390c777e6372fbc37159bc562..eae14c61437975da77d5f43a906340aaf282ec68 100644 (file)
--- a/util.cc
+++ b/util.cc
 
  */
 
-#include <cctype>                  // for isspace, isalpha, ispunct, tolower, toupper
-#include <cerrno>                  // for errno
-#include <cmath>                   // for fabs, floor
-#include <cstdarg>                 // for va_list, va_end, va_start, va_copy
-#include <cstdint>                 // for uint32_t
-#include <cstdio>                  // for size_t, vsnprintf, FILE, fopen, printf, sprintf, stderr, stdin, stdout
-#include <cstdlib>                 // for abs, getenv, calloc, free, malloc, realloc
-#include <cstring>                 // for strlen, strcat, strstr, memcpy, strcmp, strcpy, strdup, strchr, strerror
-#include <ctime>                   // for mktime, localtime
-
-#include <QtCore/QByteArray>       // for QByteArray
-#include <QtCore/QChar>            // for QChar, operator<=, operator>=
-#include <QtCore/QCharRef>         // for QCharRef
-#include <QtCore/QDateTime>        // for QDateTime
-#include <QtCore/QFileInfo>        // for QFileInfo
-#include <QtCore/QList>            // for QList
-#include <QtCore/QString>          // for QString, operator+
-#include <QtCore/QTextCodec>       // for QTextCodec
-#include <QtCore/QTextStream>      // for operator<<, QTextStream, qSetFieldWidth, endl, QTextStream::AlignLeft
-#include <QtCore/Qt>               // for CaseInsensitive
-#include <QtCore/QtGlobal>         // for qPrintable
+#include <cctype>                      // for isspace, isalpha, ispunct, tolower, toupper
+#include <cerrno>                      // for errno
+#include <cmath>                       // for fabs, floor
+#include <cstdarg>                     // for va_list, va_end, va_start, va_copy
+#include <cstdio>                      // for size_t, vsnprintf, FILE, fopen, printf, sprintf, stderr, stdin, stdout
+#include <cstdint>                     // for uint32_t
+#include <cstdlib>                     // for abs, getenv, calloc, free, malloc, realloc
+#include <cstring>                     // for strlen, strcat, strstr, memcpy, strcmp, strcpy, strdup, strchr, strerror
+#include <ctime>                       // for mktime, localtime
+
+#include <QtCore/QByteArray>           // for QByteArray
+#include <QtCore/QChar>                // for QChar, operator<=, operator>=
+#include <QtCore/QCharRef>             // for QCharRef
+#include <QtCore/QDateTime>            // for QDateTime
+#include <QtCore/QFileInfo>            // for QFileInfo
+#include <QtCore/QList>                // for QList
+#include <QtCore/QString>              // for QString
+#include <QtCore/QStringRef>           // for QStringRef
+#include <QtCore/QTextCodec>           // for QTextCodec
+#include <QtCore/QTextStream>          // for operator<<, QTextStream, qSetFieldWidth, endl, QTextStream::AlignLeft
+#include <QtCore/QXmlStreamAttribute>  // for QXmlStreamAttribute
+#include <QtCore/Qt>                   // for CaseInsensitive
+#include <QtCore/QtGlobal>             // for qAsConst, QAddConst<>::Type, qPrintable
 
 #include "defs.h"
-#include "cet.h"                   // for cet_utf8_to_ucs4
-#include "src/core/datetime.h"     // for DateTime
-#include "src/core/xmltag.h"
+#include "cet.h"                       // for cet_utf8_to_ucs4
+#include "src/core/datetime.h"         // for DateTime
+#include "src/core/xmltag.h"           // for xml_tag, xml_attribute, xml_findfirst, xml_findnext
 
 
 // First test Apple's clever macro that's really a runtime test so
@@ -1653,7 +1655,7 @@ xml_tag* xml_next(xml_tag* root, xml_tag* cur)
   return cur;
 }
 
-xml_tag* xml_findnext(xml_tag* root, xml_tag* cur, const char* tagname)
+xml_tag* xml_findnext(xml_tag* root, xml_tag* cur, const QString& tagname)
 {
   xml_tag* result = cur;
   do {
@@ -1662,25 +1664,19 @@ xml_tag* xml_findnext(xml_tag* root, xml_tag* cur, const char* tagname)
   return result;
 }
 
-xml_tag* xml_findfirst(xml_tag* root, const char* tagname)
+xml_tag* xml_findfirst(xml_tag* root, const QString& tagname)
 {
   return xml_findnext(root, root, tagname);
 }
 
-char* xml_attribute(xml_tag* tag, const char* attrname)
+QString xml_attribute(const QXmlStreamAttributes& attributes, const QString& attrname)
 {
-  char* result = nullptr;
-  if (tag->attributes) {
-    char** attr = tag->attributes;
-    while (attr && *attr) {
-      if (0 == case_ignore_strcmp(*attr, attrname)) {
-        result = attr[1];
-        break;
-      }
-      attr+=2;
+  for (const auto& attribute : attributes) {
+    if (attribute.qualifiedName().compare(attrname, Qt::CaseInsensitive) == 0) {
+      return attribute.value().toString();
     }
   }
-  return result;
+  return QString();
 }
 
 const QString get_filename(const QString& fname)
index dcf1d541aab24092a15ea2355278da7add7b587b..e3b613453d0644ec825b669020e912bbbf735a92 100644 (file)
--- a/xmltag.cc
+++ b/xmltag.cc
 
  */
 
+#include <QtCore/QString>               // for QString
+#include <QtCore/QXmlStreamAttributes>  // for QXmlStreamAttributes
+
 #include "defs.h"
-#include "cet_util.h"
 #include "src/core/xmltag.h"
-#include <cstddef>
-#include <cstdio>
-#include <cstring>
 
 static void
 free_xml_tag(xml_tag* tag)
 {
   while (tag) {
     if (tag->child) {
-      free_gpx_extras(tag->child);
-    }
-    if (tag->attributes) {
-      char** ap = tag->attributes;
-
-      while (*ap) {
-        xfree(*ap++);
-      }
-
-      xfree(tag->attributes);
+      free_xml_tag(tag->child);
     }
 
     xml_tag* next = tag->sibling;
@@ -61,52 +51,15 @@ copy_xml_tag(xml_tag** copy, xml_tag* src, xml_tag* parent)
   xml_tag* res = new xml_tag;
   *copy = res;
 
-//  memcpy(res, src, sizeof(xml_tag));
   res->tagname = (src->tagname);
   res->cdata = (src->cdata);
   res->parentcdata = (src->parentcdata);
-  if (src->attributes) {
-    char** ap = src->attributes;
-    int count = 0;
-    while (*ap) {
-      count++;
-      ap++;
-    }
-    res->attributes = (char**)xcalloc(count+1, sizeof(char*));
-    ap = src->attributes;
-    auto ap2 = res->attributes;
-    while (*ap) {
-      *ap2 = xstrdup(*ap);
-      ap++;
-      ap2++;
-    }
-  }
+  res->attributes = src->attributes;
   res->parent = parent;
   copy_xml_tag(&(res->sibling), src->sibling, parent);
   copy_xml_tag(&(res->child), src->child, res);
 }
 
-static void
-convert_xml_tag(xml_tag* tag)
-{
-  if (tag == nullptr) {
-    return;
-  }
-
-//  tag->cdata = cet_convert_string(tag->cdata);
-//  tag->parentcdata = cet_convert_string(tag->parentcdata);
-  tag->cdata = tag->cdata;
-  tag->parentcdata = tag->parentcdata;
-
-  char** ap = tag->attributes;
-  while (*ap) {
-    *ap = cet_convert_string(*ap);
-    ap++;
-  }
-  convert_xml_tag(tag->sibling);
-  convert_xml_tag(tag->child);
-}
-
 static void
 fs_xml_destroy(void* fs)
 {
@@ -125,18 +78,11 @@ fs_xml_copy(void** copy, void* source)
     *copy = nullptr;
     return;
   }
-  *copy = (void*)fs_xml_alloc(src->fs.type);
-  memcpy(*copy, source, sizeof(fs_xml));
-  copy_xml_tag(&(((fs_xml*)(*copy))->tag), src->tag, nullptr);
-}
+  fs_xml* res = new fs_xml;
+  *copy = res;
 
-static void
-fs_xml_convert(void* fs)
-{
-  fs_xml* xml = (fs_xml*)fs;
-  if (xml) {
-    convert_xml_tag(xml->tag);
-  }
+  res->fs = src->fs;
+  copy_xml_tag(&(res->tag), src->tag, nullptr);
 }
 
 fs_xml* fs_xml_alloc(long type)
@@ -145,6 +91,6 @@ fs_xml* fs_xml_alloc(long type)
   result->fs.type = type;
   result->fs.copy = fs_xml_copy;
   result->fs.destroy = fs_xml_destroy;
-  result->fs.convert = fs_xml_convert;
+  result->fs.convert = nullptr;
   return result;
 }